home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # KnowsPICT by Jon Zap
- #
- # CLUTBuilder.c - C Source
- #
- # Copyright © 1989 Apple Computer, Inc.
- # All rights reserved.
- #
- #
- # this file contains functions used to pull colors from a PICT. You activate it by
- # calling CollectColors(PicHandle) with PicHandle set to a PICT that you have already
- # loaded into memory. It will almost invariably return a (handle to a) color table
- # (that contains at least black and white) however the color table is not at all clean
- # in the current implementation. It is probably ok if you run it through NewPalette.
- # If it runs across a direct pixmap it won't bomb but it won't add any colors to the
- # color table.
- #
- # WARNING: This code has been tested but it has not been tested thoroughly;
- # USE AT YOUR OWN RISK!
- ------------------------------------------------------------------------------*/
-
- #define applec
-
- OSErr gColorError; /* to report errors from bottlenecks. */
- CTabHandle gColorTable; /* to collect colors from bottlenecks. */
- short gNextCSpec; /* next CSpec entry in color table */
- short foundDirect; /* set to true if we uncover a direct pixmap */
- short maxPixDepth; /* depth of deepest pixmap found */
-
- /* Add a color to the color table. */
- void AddRGBColor(rgb)
- RGBColor *rgb;
- {
- long numSpecs,sizeInBytes;
- int i,ctSize;
- CTabPtr TablePtr;
- RGBColor rgbx;
-
- if (gColorError)
- return;
-
- TablePtr = (*gColorTable);
- ctSize = TablePtr -> ctSize;
- for (i = 0; i <= ctSize; i++) {
- rgbx = TablePtr->ctTable[i].rgb;
- if (rgbx.red==(*rgb).red &&
- rgbx.green==(*rgb).green &&
- rgbx.blue==(*rgb).blue)
- return; /* if already there, done */
- }
- numSpecs = (long) (++(**gColorTable).ctSize); /* add a colorspec to table */
- sizeInBytes = (numSpecs * sizeof(ColorSpec)) + sizeof(ColorTable);
- SetHandleSize((Handle)gColorTable, sizeInBytes);
- if ((gColorError = MemError()) == noErr) {
- (**gColorTable).ctTable[numSpecs].rgb = *rgb;
- (**gColorTable).ctTable[numSpecs].value = 0;
- }
- }
-
- /* Add the contents of another color table to our color table.*/
- void AddColorTable(cTab)
- CTabHandle cTab;
- {
- short index,size;
- RGBColor color;
- size = (**cTab).ctSize;
- for (index= 0; index <= size; index++) {
- color = (**cTab).ctTable[index].rgb;
- AddRGBColor(&color);
- }
- }
-
- /* Add the foreground color of the current port to the color table. */
- void AddRGBForeColor()
- {
- #ifdef applec
- AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbFgColor));
- #else
- AddRGBColor(&((*(CGrafPtr)thePort).rgbFgColor));
- #endif
- }
-
- /* Add the background color of the current port to the color table. */
- void AddRGBBackColor()
- {
- #ifdef applec
- AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbBkColor));
- #else
- AddRGBColor(&((*(CGrafPtr)thePort).rgbBkColor));
- #endif
- }
-
- /* Add colors from a PixPat to a color table. */
- void AddPixPat(pPat)
- PixPatHandle pPat;
- {
- switch ((**pPat).patType) {
-
- case 0: /* one-bit patterns are drawn in the foreground and background color. */
- AddRGBForeColor();
- AddRGBBackColor();
- break;
- case 1: /* Type 1 PixPats have a color table. */
- AddColorTable((**(**pPat).patMap).pmTable);
- break;
- }
- }
-
- /* Add colors from the pen PixPat to the color table. */
- void AddPenPixPat()
- {
- #ifdef applec
- AddPixPat((*(CGrafPtr)qd.thePort).pnPixPat);
- #else
- AddPixPat((*(CGrafPtr)thePort).pnPixPat);
- #endif
- }
-
- /* Add colors from the fill PixPat to the color table. */
- void AddFillPixPat()
- {
- #ifdef applec
- AddPixPat((*(CGrafPtr)qd.thePort).fillPixPat);
- #else
- AddPixPat((*(CGrafPtr)thePort).fillPixPat);
- #endif
- }
-
- /* Add colors because we are about to draw an object. */
- void AddVerb(verb)
- GrafVerb verb;
- {
- switch (verb) {
-
- case frame:
- case paint: /* Framed and painted objects are drawn in the pen PixPat. */
- AddPenPixPat();
- break;
- case erase: /* Erased objects are drawn in the background color. */
- AddRGBBackColor();
- break;
- case fill:
- /* Filled objects are drawn in the fill PixPat. The fillPixPat is
- a pattern used to record fill commands for pictures. First, a
- command to set the fillPixPat is recorded, then the fill command
- is recorded. */
- AddFillPixPat();
- }
- }
-
- /* bottleneck routines follow . . . */
-
- pascal void ColorTextProc(byteCount, textBuf, numer, denom)
- short byteCount;
- Ptr textBuf;
- Point numer,denom;
- { /* Text is drawn with the foreground and background colors.*/
- #ifdef applec
- #pragma unused (byteCount, textBuf, numer, denom)
- #endif
- AddRGBForeColor();
- AddRGBBackColor();
- }
-
- pascal void ColorLineProc(newPt)
- Point newPt;
- { /* Lines are drawn with the pen PixPat. */
- #ifdef applec
- #pragma unused (newPt)
- #endif
- AddPenPixPat();
- }
-
- pascal void ColorRectProc(verb, r)
- GrafVerb verb;
- Rect *r;
- {
- #ifdef applec
- #pragma unused (r)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorRRectProc(verb, r, ovalWidth, ovalHeight)
- GrafVerb verb;
- Rect *r;
- short ovalWidth;
- short ovalHeight;
- {
- #ifdef applec
- #pragma unused (r, ovalWidth, ovalHeight)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorOvalProc(verb, r)
- GrafVerb verb;
- Rect *r;
- {
- #ifdef applec
- #pragma unused (r)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorArcProc(verb, r, startAngle, arcAngle)
- GrafVerb verb;
- Rect *r;
- short startAngle, arcAngle;
- {
- #ifdef applec
- #pragma unused (r, startAngle, arcAngle)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorPolyProc(verb, poly)
- GrafVerb verb;
- PolyHandle poly;
- {
- #ifdef applec
- #pragma unused (poly)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorRgnProc(verb, rgn)
- GrafVerb verb;
- RgnHandle rgn;
- {
- #ifdef applec
- #pragma unused (rgn)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorBitsProc(bitPtr, srcRect, dstRect, mode, maskRgn)
- BitMap *bitPtr;
- Rect *srcRect, *dstRect;
- short mode;
- RgnHandle maskRgn;
- {
- #ifdef applec
- #pragma unused (srcRect, dstRect, mode, maskRgn)
- #endif
- PixMapPtr aPixMap;
- short tempRB;
-
- /* Get the PixMap that we are about to draw. SrcBits might be a BitMap, or
- one of two different kinds of PixMap pointers. */
- tempRB = (*bitPtr).rowBytes; /* local copy of rowBytes */
- if (tempRB < 0) { /* high bit set? */
- if ((tempRB<<1) < 0) /* next to high bit set? */
- aPixMap = (** ( (PixMapHandle *)bitPtr )); /* ptr to PixMap handle */
- else
- aPixMap = (PixMapPtr) bitPtr; /* pointer to a PixMap */
- if ((*aPixMap).pixelSize > maxPixDepth) /* deepest pixmap so far? */
- maxPixDepth = (*aPixMap).pixelSize;
- if ((*aPixMap).pixelType==16) {
- foundDirect = true;
- return; /* direct pixmap? eek! */
- }
- AddColorTable((*aPixMap).pmTable); /* it has its own color table. */
- }
- else {
- /* It's just a BitMap; it will use the background and foreground colors. */
- AddRGBBackColor();
- AddRGBForeColor();
- }
- }
-
- RGBColor whiteRGB = { 0xFFFF,0xFFFF,0xFFFF };
- RGBColor blackRGB = { 0,0,0 };
-
- CTabHandle CollectColors(fromPicture, depthPtr, directFlagPtr)
- PicHandle fromPicture;
- short *depthPtr;
- short *directFlagPtr;
- {
- CTabHandle colors;
- CQDProcs bottlenecks;
-
- /* Set the bottlenecks. These bottlenecks will figure out what colors are in
- a picture, but won't draw anything.
- Note: the bottlenecks are installed in thePort, which must be a color port.
- */
- SetStdCProcs(&bottlenecks);
- bottlenecks.textProc = (Ptr) ColorTextProc;
- bottlenecks.lineProc = (Ptr) ColorLineProc;
- bottlenecks.rectProc = (Ptr) ColorRectProc;
- bottlenecks.rRectProc = (Ptr) ColorRRectProc;
- bottlenecks.ovalProc = (Ptr) ColorOvalProc;
- bottlenecks.arcProc = (Ptr) ColorArcProc;
- bottlenecks.polyProc = (Ptr) ColorPolyProc;
- bottlenecks.rgnProc = (Ptr) ColorRgnProc;
- bottlenecks.bitsProc = (Ptr) ColorBitsProc;
-
- /* Create a color table containing black and white. */
- foundDirect = false; /* haven't found a direct pixmap yet */
- maxPixDepth = 1; /* assume we will find a bitmap */
- colors = (CTabHandle) NewHandle( sizeof(ColorTable) + sizeof(ColorSpec) );
- if (colors) {
- (**colors).ctSize = 1; /* 2 entries */
- #ifdef applec
- (**colors).ctFlags = 0x8000;
- #else
- (**colors).transIndex = 0x8000;
- #endif
- (**colors).ctSeed = GetCTSeed();
- (**colors).ctTable[0].rgb = whiteRGB; /*first entry is white*/
- (**colors).ctTable[1].rgb = blackRGB; /*second entry is black*/
- /* Now play back the picture to get the colors. The dstRect doesn't
- matter since our bottlenecks will never actually draw. We use global
- variables (gColorError and gColorTable) to communicate with the
- bottlenecks. */
- #ifdef applec
- (*(qd.thePort)).grafProcs = (QDProcs *) &bottlenecks;
- #else
- (*thePort).grafProcs = (QDProcs *) &bottlenecks;
- #endif
- gColorError = noErr;
- gColorTable = colors;
- DrawPicture(fromPicture, &((**fromPicture).picFrame));
- #ifdef applec
- (*(qd.thePort)).grafProcs = 0L;
- #else
- (*thePort).grafProcs = 0L;
- #endif
- *depthPtr = maxPixDepth;
- *directFlagPtr = foundDirect;
-
- /* Fail if error occurred while within the color bottlenecks. */
- if (gColorError != noErr) {
- DisposHandle((Handle)colors);
- colors = 0L;
- }
- }
- return colors;
- }
-